package com.xrkj.b2c.service.impl.bus;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xrkj.b2c.exception.BusinessException;
import com.xrkj.b2c.model.bus.BusOrder;
import com.xrkj.b2c.service.bus.PnrInputService;
import com.xrkj.b2c.utils.StringUtil;

/**
 * 
 * <B>系统名称：</B><BR>
 * <B>模块名称：</B><BR>
 * <B>中文类名：</B>解析PNR服务类<BR>
 * <B>概要说明：</B><BR>
 * @author 赵子靖
 * @since 2018年07月15日
 */
@Service
public class PnrInputServiceImpl implements PnrInputService {

    /**
     * 
     * <B>方法名称：</B>PNR内容解析<BR>
     * <B>概要说明：</B><BR>
     * @author perry
     * @since 2018年7月11日    
     * @param pnrContent
     * @return
     */
    @Override
    public List<BusOrder> parsePnrContent(String pnrContent) {
        if(StringUtil.isEmpty(pnrContent)){
            throw new BusinessException("解析出错，请输入需要解析的PNR编码。");
        }
        List<BusOrder> pnrOrders = new ArrayList<BusOrder>();
        JSONObject pnrData = JSONObject.parseObject(pnrContent);
        JSONArray pnrs = pnrData.getJSONArray("data");
        this.checkPnr(pnrs);
        if(pnrs!=null && pnrs.size()>0){
            //step1、先找出乘机人姓名  同时找出乘机人pnr码q4
            this.findPnrName(pnrs, pnrOrders);
            //step2、找出票号和行程
            this.findPnrTicket(pnrs, pnrOrders);
            
        }
        if(CollectionUtils.isEmpty(pnrOrders)){
            throw new BusinessException("抱歉，没有解析到任何结果，请确保您的PNR编码正确。");
        }
        //数据后续处理
        if(!CollectionUtils.isEmpty(pnrOrders)){
            for (BusOrder order : pnrOrders) {
                if(StringUtil.isEmpty(order.getoRoute())){  
                    order.setoRoute(pnrOrders.get(0).getoRoute());
                }
                order.setoRoute(this.regRoute(order.getoRoute()));
            }
        }
        return pnrOrders;
    }
    
    /**
     * 
     * <B>方法名称：</B>航程增加横线<BR>
     * <B>概要说明：</B><BR>
     * @author perry
     * @since 2018年7月22日 	
     * @param route
     * @return
     */
    private String regRoute(String route){
        if(StringUtil.isEmpty(route)){
            return "";
        }
        String regex = "(.{3})";
        String result = route.replaceAll (regex, "$1-");
        if(result.substring(result.length()-1,result.length()).contains("-")){
            result = result.substring(0,result.length()-1);
        }
        String[] strs = result.split("-");
        if(strs!=null && strs.length>0){
            result = "";
            for(int i=0;i<strs.length;i++){
                if(StringUtil.isEmpty(result)){
                    result += strs[i];
                }else{
                    if(result.substring(result.length()-3,result.length()).equals(strs[i])){
                        //前一位已经存在 
                        continue;
                    }else{
                        result += "-"+strs[i];
                    }
                }
            }
        }
        return result;
    }
    
    /**
     * 
     * <B>方法名称：</B>校验pnr格式是否正确<BR>
     * <B>概要说明：</B><BR>
     * @author perry
     * @since 2018年7月12日 	
     * @param pnrs
     */
    private void checkPnr(JSONArray pnrs){
        if(pnrs==null){
            throw new BusinessException("pnr格式错误，pnr为空，请重新输入。");
        }
        if(pnrs.size()==1){
            throw new BusinessException("pnr格式错误，行数过少，请重新输入。");
        }
        if(pnrs.get(0)==null){
            throw new BusinessException("pnr格式错误，第一行不能为空行。");
        }
        if(!pnrs.getString(0).contains("/") && !this.isCNChar(pnrs.getString(0))){
            throw new BusinessException("pnr格式错误，请重新输入正确的pnr。");
        }
    }
    
    /**
     * 
     * <B>方法名称：</B>解析找出乘机人姓名<BR>
     * <B>概要说明：</B><BR>
     * @author perry
     * @since 2018年7月12日
     */
    private void findPnrName(JSONArray pnrs,List<BusOrder> pnrOrders){
        String pnr = "";
        for(int i=0;i<pnrs.size();i++){
            //切分列
            if(pnrs.get(i)==null){
                continue;
            }
            JSONArray cols = pnrs.getJSONArray(i);
            if(cols!=null && cols.size()>0){
                for(int j=0;j<cols.size();j++){
                    if((this.isCNChar(cols.getString(j)) && cols.size()<4) || (cols.getString(j).contains("/") && cols.size()<4) || (cols.getString(j).contains("/") && cols.size()<5 && (cols.getString(j+1).contains("CHD") || cols.getString(j+1).contains("MISS") || cols.getString(j+1).contains("MR") || cols.getString(j+1).contains("MS")))){
                        //可能是乘机人
                        BusOrder busOrder = new BusOrder();
                        busOrder.setoName(cols.getString(j).contains(".")?cols.getString(j).substring(cols.getString(j).indexOf(".")+1,cols.getString(j).length()):cols.getString(j));
                        //如果有数字则不是乘机人
                        Pattern patter = Pattern.compile(".*\\d+.*");
                        Matcher matcher = patter.matcher(busOrder.getoName());
                        if(matcher.matches()){
                            break;
                        }
                        pnrOrders.add(busOrder);
                        //尝试获取紧跟着的pnr 如果没有可能会抛出下标越界异常
                        try{
                            if(StringUtil.isEmpty(cols.getString(j+1))){
                                break;
                            }
                            if(cols.getString(j+1).length()==6){
                                //一般pnr都会在姓名往后下一位是pnr 并且6位英文字符
                                pnr = cols.getString(j+1);
                                busOrder.setoPnr(pnr);
                            }else if(cols.getString(j+2).length()==6){
                                //尝试往后取两位
                                pnr = cols.getString(j+2);
                                busOrder.setoPnr(pnr);
                            }
                        }catch(Exception e){
                            //有可能下表越界 什么都不用处理即可
                        }
                        break;
                    }
                }
            }
        }
        //补全pnr
        if(!CollectionUtils.isEmpty(pnrOrders)){
            for (BusOrder order : pnrOrders) {
                if(StringUtil.isEmpty(order.getoPnr())){
                   order.setoPnr(pnr); 
                }
            }
        }
    }
    
    /**
     * 
     * <B>方法名称：</B>判断是否包含中文<BR>
     * <B>概要说明：</B><BR>
     * @author perry
     * @since 2018年7月22日 	
     * @param s
     * @return
     */
    private boolean isCNChar(String s){
        boolean booleanValue = false;
        for(int i=0; i<s.length(); i++){
            char c = s.charAt(i);
            if(c > 128){
                booleanValue = true;
                break;
            }
        }
        return booleanValue;
    }
    
    /**
     * 
     * <B>方法名称：</B>解析pnr找出票号和行程<BR>
     * <B>概要说明：</B><BR>
     * @author perry
     * @since 2018年7月12日 	
     * @param pnrs
     * @param pnrOrders
     */
    private void findPnrTicket(JSONArray pnrs,List<BusOrder> pnrOrders){
        boolean hasParserTicketSuccess = false; //是否解析到行程值
        //step1、先尝试解析带票号的
        int ticketNum = 0; //票号数记录
        for(int i=0;i<pnrs.size();i++){
            //切分列
            if(pnrs.get(i)==null){
                continue;
            }
            JSONArray cols = pnrs.getJSONArray(i);
            if(cols!=null && cols.size()>0){
                for(int j=0;j<cols.size();j++){
                    if(cols.getString(j).contains("/P") && cols.size()>7){
                        //有带票号解析成功标识
                        hasParserTicketSuccess = true;
                        //可能是带有票号的一行
                        String rowNumStr = cols.getString(j).substring(cols.getString(j).length()-1,cols.getString(j).length());
                        if(!StringUtil.isEmpty(rowNumStr)){
                            ++ticketNum;
                            int rowNum = Integer.parseInt(rowNumStr); 
                            try{
                                //尝试根据票号获取乘机人是否存在，不存在则会抛出下标越界
                                pnrOrders.get(ticketNum);
                            }catch(IndexOutOfBoundsException e){
                                //下标越界再考虑范围之内 此处应该将乘机人信息扩充
                                for(int tempNum=pnrOrders.size();tempNum<ticketNum;tempNum++){
                                    BusOrder busOrder = new BusOrder();
                                    busOrder.setoName(pnrOrders.get(0).getoName());
                                    busOrder.setoPnr(pnrOrders.get(0).getoPnr());
                                    pnrOrders.add(busOrder);
                                }
                            }
                            if(!StringUtil.isEmpty(pnrOrders.get(rowNum-1).getoTicketNo())){
                                //票号
                                pnrOrders.get(ticketNum-1).setoTicketNo(cols.getString(j).substring(0,cols.getString(j).length()-5));
                                //行程 （票号往前移三列）
                                pnrOrders.get(ticketNum-1).setoRoute(cols.getString(j-3));
                            }else{
                                //票号
                                pnrOrders.get(rowNum-1).setoTicketNo(cols.getString(j).substring(0,cols.getString(j).length()-5));
                                //行程
                                pnrOrders.get(ticketNum-1).setoRoute(cols.getString(j-3));
                            }
                        }
                        break;
                    }
                }
            }
        }
        if(hasParserTicketSuccess){
            return;
        }
        
        //step2、不带票号的pnr解析
        String route = "";
        if(pnrOrders.size()>1){
            //不带票号的pnr 并且有多个乘机人
            for(int i=0;i<pnrs.size();i++){
                //切分列
                if(pnrs.get(i)==null){
                    continue;
                }
                JSONArray cols = pnrs.getJSONArray(i);
                if(cols!=null && cols.size()>0){
                    for(int j=0;j<cols.size();j++){
                        if(cols.getString(j).contains("ARNK")){
                            break;
                        }
                        try{
                            //带有SEAME字样或者有字符等于6 并且col大于8 有可能是行程行
                            if((cols.getString(j).contains("SEAME") && cols.size()>8) || (cols.getString(j).length()==6 && this.isMonth(cols.getString(j-1).substring(cols.getString(j-1).length()-3,cols.getString(j-1).length())))){
                                //一般第五位是行程
                                if(cols.getString(4).length()==6){
                                    //第五位命中行程
                                    //pnrOrders.get(tempPnrRow).setoRoute(cols.getString(4));
                                    route += cols.getString(4);
                                    //tempPnrRow++;
                                    break;
                                }else if(cols.getString(3).length()==6){
                                    //往前移一位   第四位命中行程
                                    //pnrOrders.get(tempPnrRow).setoRoute(cols.getString(3));
                                    route += cols.getString(4);
                                    //tempPnrRow++;
                                    break;
                                }
                            }
                        }catch(Exception e){
                            //什么都不做
                        }
                    }
                }
            }
            //对航段判断进行赋值
            for (BusOrder busOrder : pnrOrders) {
                busOrder.setoRoute(route);
            }
        }else if(pnrOrders.size()==1){
            //不带票号的pnr 并且有多个乘机人
            for(int i=0;i<pnrs.size();i++){
                //切分列
                if(pnrs.get(i)==null){
                    continue;
                }
                JSONArray cols = pnrs.getJSONArray(i);
                if(cols!=null && cols.size()>0){
                    for(int j=0;j<cols.size();j++){
                        if(cols.getString(j).contains("ARNK")){
                            break;
                        }
                        //带有SEAME字样或者有字符等于6 并且col大于8 有可能是行程行
                        try{
                            if((cols.getString(j).contains("SEAME") && cols.size()>8) || (cols.getString(j).length()==6 && this.isMonth(cols.getString(j-1).substring(cols.getString(j-1).length()-3,cols.getString(j-1).length())))){
                                //                                if(tempPnrRow>0){
//                                    //创建pnrOrder
//                                    BusOrder order = new BusOrder(); 
//                                    order.setoName(pnrOrders.get(0).getoName());
//                                    order.setoPnr(pnrOrders.get(0).getoPnr());
//                                    pnrOrders.add(order);
//                                }
                                //一般第五位是行程
                                if(cols.getString(4).length()==6){
                                    //第五位命中行程
                                    //pnrOrders.get(tempPnrRow).setoRoute(cols.getString(4));
                                    route += cols.getString(4);
                                    //tempPnrRow++;
                                    break;
                                }else if(cols.getString(3).length()==6){
                                    //往前移一位   第四位命中行程
                                    //pnrOrders.get(tempPnrRow).setoRoute(cols.getString(3));
                                    route += cols.getString(3);
                                    //tempPnrRow++;
                                    break;
                                }
                            }
                        }catch(Exception e){
                            //不做处理
                        }
                    }
                }
            }
            //对航段判断进行赋值
            for (BusOrder busOrder : pnrOrders) {
                busOrder.setoRoute(route);
            }
        }
        
    }
    
    /**
     * 
     * <B>方法名称：</B>判断是否是月份<BR>
     * <B>概要说明：</B><BR>
     * @author perry
     * @since 2018年7月22日 	
     * @param month
     * @return
     */
    public boolean isMonth(String month){
        if(StringUtil.isEmpty(month)){
            return false;
        }
        switch (month) {
        case "FEB":
            return true;
        case "MAR":
            return true;    
        case "APR":
            return true;  
        case "MAY":
            return true; 
        case "JUN":
            return true;
        case "JUL":
            return true;
        case "AUG":
            return true;
        case "SEP":
            return true;
        case "OCT":
            return true;
        case "NOV":
            return true;
        case "DEC":
            return true;
        default:
            return false;
        }
    }
    
}
